home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / russell / gc32.lha / checksums.c < prev    next >
C/C++ Source or Header  |  1993-07-29  |  4KB  |  139 lines

  1. # ifdef CHECKSUMS
  2.  
  3. # include "gc_private.h"
  4.  
  5. /* This is debugging code intended to verify the results of dirty bit    */
  6. /* computations. Works only in a single threaded environment.        */
  7. /* We assume that stubborn objects are changed only when they are     */
  8. /* enabled for writing.  (Certain kinds of writing are actually        */
  9. /* safe under other conditions.)                    */
  10. # define NSUMS 2000
  11.  
  12. # define OFFSET 100000
  13.  
  14. typedef struct {
  15.     bool new_valid;
  16.     word old_sum;
  17.     word new_sum;
  18.     struct hblk * block;    /* Block to which this refers + OFFSET  */
  19.                 /* to hide it from colector.        */
  20. } page_entry;
  21.  
  22. page_entry GC_sums [NSUMS];
  23.  
  24. word GC_checksum(h)
  25. struct hblk *h;
  26. {
  27.     register word *p = (word *)h;
  28.     register word *lim = (word *)(h+1);
  29.     register word result = 0;
  30.     
  31.     while (p < lim) {
  32.         result += *p++;
  33.     }
  34.     return(result);
  35. }
  36.  
  37. # ifdef STUBBORN_ALLOC
  38. /* Check whether a stubborn object from the given block appears on    */
  39. /* the appropriate free list.                        */
  40. bool GC_on_free_list(h)
  41. struct hblk *h;
  42. {
  43.     register hdr * hhdr = HDR(h);
  44.     register int sz = hhdr -> hb_sz;
  45.     ptr_t p;
  46.     
  47.     if (sz > MAXOBJSZ) return(FALSE);
  48.     for (p = GC_sobjfreelist[sz]; p != 0; p = obj_link(p)) {
  49.         if (HBLKPTR(p) == h) return(TRUE);
  50.     }
  51.     return(FALSE);
  52. }
  53. # endif
  54.  
  55. int GC_n_dirty_errors;
  56. int GC_n_changed_errors;
  57. int GC_n_clean;
  58. int GC_n_dirty;
  59.  
  60. void GC_update_check_page(h, index)
  61. struct hblk *h;
  62. int index;
  63. {
  64.     page_entry *pe = GC_sums + index;
  65.     register hdr * hhdr = HDR(h);
  66.     
  67.     if (pe -> block != 0 && pe -> block != h + OFFSET) ABORT("goofed");
  68.     pe -> old_sum = pe -> new_sum;
  69.     pe -> new_sum = GC_checksum(h);
  70.     if (GC_page_was_dirty(h)) {
  71.         GC_n_dirty++;
  72.     } else {
  73.         GC_n_clean++;
  74.     }
  75.     if (pe -> new_valid && pe -> old_sum != pe -> new_sum) {
  76.         if (!GC_page_was_dirty(h)) {
  77.             /* Set breakpoint here */GC_n_dirty_errors++;
  78.         }
  79. #    ifdef STUBBORN_ALLOC
  80.           if (!IS_FORWARDING_ADDR_OR_NIL(hhdr)
  81.             && hhdr -> hb_map != GC_invalid_map
  82.             && hhdr -> hb_obj_kind == STUBBORN
  83.             && !GC_page_was_changed(h)
  84.             && !GC_on_free_list(h)) {
  85.             /* if GC_on_free_list(h) then reclaim may have touched it    */
  86.             /* without any allocations taking place.            */
  87.             /* Set breakpoint here */GC_n_changed_errors++;
  88.           }
  89. #    endif
  90.     }
  91.     pe -> new_valid = TRUE;
  92.     pe -> block = h + OFFSET;
  93. }
  94.  
  95. /* Should be called immediately after GC_read_dirty and GC_read_changed. */
  96. void GC_check_dirty()
  97. {
  98.     register int index;
  99.     register int i;
  100.     register struct hblk *h;
  101.     register ptr_t start;
  102.     
  103.     GC_n_dirty_errors = 0;
  104.     GC_n_changed_errors = 0;
  105.     GC_n_clean = 0;
  106.     GC_n_dirty = 0;
  107.     
  108.     index = 0;
  109.     for (i = 0; i < GC_n_heap_sects; i++) {
  110.         start = GC_heap_sects[i].hs_start;
  111.         for (h = (struct hblk *)start;
  112.              h < (struct hblk *)(start + GC_heap_sects[i].hs_bytes);
  113.              h++) {
  114.              GC_update_check_page(h, index);
  115.              index++;
  116.              if (index >= NSUMS) goto out;
  117.         }
  118.     }
  119. out:
  120.     GC_printf2("Checked %lu clean and %lu dirty pages\n",
  121.               (unsigned long) GC_n_clean, (unsigned long) GC_n_dirty);
  122.     if (GC_n_dirty_errors > 0) {
  123.         GC_printf1("Found %lu dirty bit errors\n",
  124.                (unsigned long)GC_n_dirty_errors);
  125.     }
  126.     if (GC_n_changed_errors > 0) {
  127.         GC_printf1("Found %lu changed bit errors\n",
  128.                (unsigned long)GC_n_changed_errors);
  129.     }
  130. }
  131.  
  132. # else
  133.  
  134. extern int GC_quiet;
  135.     /* ANSI C doesn't allow translation units to be empty.    */
  136.     /* So we guarantee this one is nonempty.        */
  137.  
  138. # endif /* CHECKSUMS */
  139.